Zadanie: Wykorzystanie szablonów w projekcie

Czas użyć szablonów HTML w naszym blogu!

Skrypt, który do tej pory napisaliśmy, generuje fragmenty kodu HTML w pięciu miejscach:

  1. dla linka do artykułu, umieszczanego w lewej kolumnie,
  2. dla linka do tagu, umieszczanego na końcu każdego artykułu,
  3. dla linka do autora, umieszczanego pod tytułem każdego artykułu,
  4. dla linka do tagu, umieszczanego w chmurze tagów w prawej kolumnie,
  5. dla linka do autora, umieszczanego na liście w prawej kolumnie.

Dla pozycji 1-3 zastosuj szablony pojedynczego linka, czyli wedle przykładu wykorzystującego tplHello.

Dla pozycji 4-5 zastosuj szablony zawierające pętlę. Aby je wykorzystać, w swoim kodzie musisz odnaleźć miejsca, w których generujesz kod tych linków. Zamiast generować kod, stwórz obiekt i wypełniaj go danymi w takiej strukturze, jakiej będzie wymagał szablon.

Handlebars a ESLint

ESLint domyślnie zakłada, że elementy, które znajdują się poza danym plikiem, nie mogą być w nim użyte, dopóki ich nie zaimportujemy (np. przy użyciu instrukcji import). Nie bierze jednak pod uwagę, że dodając do pliku HTML kilka plików JS przy użyciu tagu <script>, mogą one korzystać nawzajem ze swojej zawartości i wtedy wcale nie musimy niczego importować. Na przykład, gdy dodamy do index.html informację o a.js i b.js, w tym drugim pliku będziemy mogli korzystać z pierwszego bez żadnych problemów.

Tym samym może dojść do sytuacji, w której Twój kod działa poprawnie, a jednak ESLint wyrzuca błąd mówiący, że Handlebars są niezdefiniowane. Możemy jednak łatwo to naprawić. Wystarczy poinformować ESLint, że jest to coś globalnego i powinien zakładać, że każdy plik JS ma do niego dostęp. Możesz to zrobić, dodając do pliku eslintrc.json regułę:

"globals": {
  "Handlebars": false
}

Jak zastosować Handlebars w projekcie?

Zaczynamy od dodania skryptu Handlebars. W kodzie HTML znajdź tę linię kodu:

<script src="js/script.js"></script>

I nad nią umieść tę linię:

<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.1.0/handlebars.min.js"></script>

Ten skrypt dodajemy tylko raz, niezależnie od tego ilu szablonów będziemy używać.

Teraz przed tą linią wstaw swój pierwszy szablon:

<script id="template-article-link" type="text/x-handlebars-template">
  <li><a href="#{{ id }}"><span>{{ title }}</span></a></li>
</script>

Następnie na początku swojego pliku JS wstaw ten kod:

const templates = {
  articleLink: Handlebars.compile(document.querySelector('#template-article-link').innerHTML)
}

Dodając później kolejne szablony, będziesz rozbudowywać obiekt templates, aby wszystkie mieć zebrane w jednym miejscu. Wystarczy, że skopiujesz tę linię i zmienisz klucz articleLink i selektor #template-article-link.

Kolejnym krokiem jest wykorzystanie szablonu – zacznij od znalezienia tej linii kodu:

const linkHTML = '<li><a href="#' + articleId + '"><span>' + articleTitle + '</span></a></li>';

Zamień ją na następującą:

const linkHTMLData = {id: articleId, title: articleTitle};
const linkHTML = templates.articleLink(linkHTMLData);

W ten sposób wykonaliśmy pkt. 1 tego zadania. Punkty 2 i 3 wykonaj, powtarzając te same kroki.

Dla punktów 4 i 5 będzie odrobinę trudniej. Omówmy sobie pokrótce wykonanie pkt. 4.

1. Zacznij od dodania pustego szablonu w kodzie HTML oraz w obiekcie templates. Założymy, że ten szablon będzie miał klucz tagCloudLink, czyli będziemy go używać jako templates.tagCloudLink.

2. Najpierw znajdujesz let allTagsHTML = ''; – to zmienna, w której przechowujemy kod HTML wszystkich linków do tagów. Nie będzie już nam potrzebna, a zamiast niej chcemy mieć:

const allTagsData = {tags: []};

3. Następnie znajdujemy linię allTagsHTML += tagLinkHTML;. Ta linia doklejała kod kolejnego linka do allTagsHTML. Zamiast tego, chcemy do tablicy allTagsHTML dodawać kolejny obiekt, np.:

allTagsData.tags.push({
  tag: tag,
  count: allTags[tag],
  className: calculateTagClass(allTags[tag], tagsParams)
});

4. Teraz znajdujemy linię tagList.innerHTML = allTagsHTML; – nie mamy już allTagsHTML, więc zamieniamy tę linię na:

tagList.innerHTML = templates.tagCloudLink(allTagsData);

To jest też dobre miejsce, aby za pomocą console.log sprawdzić, jak wygląda zawartość allTagsData.

5. Wszystko powinno działać, ale do tej pory nasz szablon był pusty. Zacznij od wstawienia w nim jakiegoś tekstu, aby sprawdzić, czy ten tekst wyświetli się tylko raz na stronie. Jeśli tak, wszystko działa poprawnie. Teraz w naszym szablonie potrzebujemy zrobić pętlę. Zacznij od takiego szablonu:

<script id="template-tag-cloud-link" type="text/x-handlebars-template">
  {{#each tags}}
  <li>{{ tag }}</li>
  {{/each}}
</script>

Na stronie, w prawej kolumnie, powinna pojawić się lista tagów. Nie są one jednak jeszcze linkami, i nie mają klas odpowiedzialnych za rozmiar tagu. Aby sobie z tym poradzić, użyj właściwości count i className w swoim szablonie.

Dokończenie zadania

Reszta rozwiązania będzie bardzo podobna do powyższych kroków. Nie bój się eksperymentować i używać console.log do sprawdzania, czy jesteś na dobrym tropie.

Dzięki tym zmianom cały kod HTML znajdzie się pliku HTML, a nasz kod JS będzie korzystał z szablonów. To bardzo przydatna umiejętność, którą będziemy wykorzystywać w kolejnych modułach.

;